﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MemDBAPI
{
    public class ResultDataSet
    {
        public const  int INVALID_INTEGER_VALUE = 2147483647;
        public const float INVALID_FLOAT_VALUE = 3.402823466e+38F;
        public const string NULL_VALUE = "NULL";
        struct ColumnHeader
        {
            public string ColumnName;
            public int DataType;
        }

        List<ColumnHeader> columnList = new List<ColumnHeader>();

        List<List<Object>> dataTable = new List<List<object>>();

        public bool isEmpty()
        {
            return columnList.Count == 0;
        }
        public void FillGridView(DataGridView dg)
        {
            dg.Columns.Clear();
            dg.Rows.Clear();
            int k = 0;
            int allWidth = dg.Width;
            foreach (ColumnHeader ch in columnList)
            {
                dg.Columns.Add("col" + k, ch.ColumnName);
                ++ k;
            }
            int oneWidth = allWidth / k;

            if (((List<Object>)dataTable[0]).Count > 0)
            {
                // Set the columns count
                dg.Rows.Add(((List<Object>)dataTable[0]).Count);

                for (int i = 0; i < dataTable.Count; ++i)
                {
                    dg.Columns[i].Width = oneWidth;

                    try
                    {
                        List<Object> col = (List<Object>)dataTable[i];
                        int j = 0;
                        foreach (Object obj in col)
                        {
                            switch (columnList[i].DataType)
                            {
                                case 0:
                                    Int32 itg = (Int32)obj;
                                    if (itg == INVALID_INTEGER_VALUE)
                                    {
                                        dg.Rows[j].Cells[i].Value = NULL_VALUE;
                                        break;
                                    }
                                    dg.Rows[j].Cells[i].Value = itg;
                                    break;
                                case 1:
                                    Double db = (Double)obj;
                                    if (db == INVALID_FLOAT_VALUE)
                                    {
                                        dg.Rows[j].Cells[i].Value = NULL_VALUE;
                                        break;
                                    }
                                    dg.Rows[j].Cells[i].Value = db;
                                    break;
                                case 2:
                                    String str = (String)obj;
                                    dg.Rows[j].Cells[i].Value = str;
                                    break;
                            }
                            ++j;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
            }
        }

        public bool ConvertData(byte[] data_buffer)
        {
            int currentPos = 0;
            int strSize = 0;
            byte[] tempBuffer;
            byte[] tempInt = new byte[4];

            int dataInt;
            double dataDouble;
            string dataString;

            int columnSize = BitConverter.ToInt32(data_buffer, currentPos);
            currentPos += sizeof(int);

            ColumnHeader columnInfo;

            for (int i = 0; i < columnSize; i++)
            {
                columnInfo = new ColumnHeader();

                columnInfo.DataType = BitConverter.ToInt32(data_buffer, currentPos);
                currentPos += sizeof(int);

                strSize = BitConverter.ToInt32(data_buffer, currentPos);
                currentPos += sizeof(int);

                tempBuffer = new byte[strSize];
                Buffer.BlockCopy(data_buffer, currentPos, tempBuffer, 0, strSize);
                currentPos += strSize;

                columnInfo.ColumnName = Encoding.Unicode.GetString(tempBuffer);

                columnList.Add(columnInfo);
            }

            int tuple_num = BitConverter.ToInt32(data_buffer, currentPos);
            currentPos += sizeof(int);

            for (int i = 0; i < columnSize; i++)
            {
                dataTable.Add(new List<object>());
            }

            for (int i = 0; i < tuple_num; i++)
            {
                for (int j = 0; j < columnSize; j++)
                {
                    switch (columnList[j].DataType)
                    {
                        case 0:
                            dataInt = BitConverter.ToInt32(data_buffer, currentPos);
                            currentPos += sizeof(int);
                            dataTable[j].Add(dataInt);

                            break;

                        case 1:
                            dataDouble = BitConverter.ToDouble(data_buffer, currentPos);
                            currentPos += sizeof(double);
                            dataTable[j].Add(dataDouble);

                            break;

                        case 2:
                            strSize = BitConverter.ToInt32(data_buffer, currentPos);
                            currentPos += sizeof(int);

                            tempBuffer = new byte[strSize];
                            Buffer.BlockCopy(data_buffer, currentPos, tempBuffer, 0, strSize);
                            currentPos += strSize;

                            dataString = Encoding.Unicode.GetString(tempBuffer);

                            dataTable[j].Add(dataString);

                            break;
                    }
                }
            }
            return true;
        }
       
        public int getRowCount()
        {
            if (dataTable != null && dataTable.Count > 0)
            {
                if(dataTable[0] != null)
                {
                    return dataTable[0].Count;
                }
            }
            return 0;
        }
    }

}
